/*
 *  Copyright 2019-2020 Zheng Jie
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package me.zhengjie.modules.system.service.impl

import cn.hutool.core.lang.Dict
import cn.hutool.core.util.RandomUtil
import cn.hutool.extra.template.TemplateConfig
import cn.hutool.extra.template.TemplateEngine
import cn.hutool.extra.template.TemplateUtil
import me.zhengjie.common.exception.BadRequestException
import me.zhengjie.common.utils.RedisUtil
import me.zhengjie.modules.system.service.VerifyService
import me.zhengjie.tools.domain.vo.EmailVo
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

/**
 * @author Zheng Jie
 * @date 2018-12-26
 */
@Service
class VerifyServiceImpl (
    @Value("\${code.expiration}")
    private val expiration: Long,
    private val redisUtils: RedisUtil
): VerifyService {
    @Transactional(rollbackFor = [Exception::class])
    override fun sendEmail(email: String?, key: String?): EmailVo? {
        val emailVo: EmailVo
        val content: String
        val redisKey = key + email
        // 如果不存在有效的验证码，就创建一个新的
        val engine: TemplateEngine =
            TemplateUtil.createEngine(TemplateConfig("template", TemplateConfig.ResourceMode.CLASSPATH))
        val template = engine.getTemplate("email.ftl")
        val oldCode: Any = redisUtils!!.get(redisKey)!!
        if (oldCode == null) {
            val code = RandomUtil.randomNumbers(6)
            // 存入缓存
            if (!redisUtils.set(redisKey, code, expiration!!)) {
                throw BadRequestException("服务异常，请联系网站负责人")
            }
            content = template.render(Dict.create().set("code", code))
            emailVo = EmailVo(listOf(email!!), "ELADMIN后台管理系统", content)
            // 存在就再次发送原来的验证码
        } else {
            content = template.render(Dict.create().set("code", oldCode))
            emailVo = EmailVo(listOf(email!!), "ELADMIN后台管理系统", content)
        }
        return emailVo
    }

    override fun validated(key: String?, code: String?) {
        val value: Any = redisUtils!!.get(key)!!
        if (value == null || value.toString() != code) {
            throw BadRequestException("无效验证码")
        } else {
            redisUtils.del(key)
        }
    }
}